import re

from django.conf import settings
from django.core.files.uploadedfile import InMemoryUploadedFile
from rest_framework import serializers
from rest_framework.response import Response

from apps.users.models import User
from apps.goods.models import SPUSpecification, SPU, SKUImage, SKU, SpecificationOption, GoodsCategory, SKUSpecification
from libs.celery_tasks.generate_detail_html.tasks import gen_detail_html


class UsersSerializer(serializers.HyperlinkedModelSerializer):
    """用户表序列化器"""
    class Meta:
        model = User
        fields = ['id', 'username', 'password', 'email', 'mobile']
        write_only_fields = ['password']
        extra_kwargs = {
            "username": {'max_length': 20, 'min_length': 5},
            "password": {'max_length': 20, 'min_length': 8}
        }

    def validate_mobile(self, mobile):
        try:
            assert len(mobile) == 11, '手机号长度错误'
            assert re.match(r'^1[3-9]\d{9}', mobile), '手机号格式错误'
        except AssertionError as e:
            raise serializers.ValidationError(str(e))

        return mobile

    def create(self, validated_data):
        # 重写create方法,否则password字段无效
        user = User.objects.create_user(**validated_data)
        return user


class SPUOptineSerializer(serializers.ModelSerializer):
    class Meta:
        model = SpecificationOption
        fields = ['id', 'value']


class SPUSpecsSerializer(serializers.ModelSerializer):
    spu = serializers.StringRelatedField(read_only=True)
    spu_id = serializers.IntegerField()
    options = SPUOptineSerializer(read_only=True, many=True)

    class Meta:
        model = SPUSpecification
        fields = ['id', 'name', 'spu', 'spu_id', 'options']


class SimpleSPUSerializer(serializers.ModelSerializer):
    class Meta:
        model = SPU
        fields = ['id', 'name']
        read_only_fields = ['id', 'name']


class SPUSerializer(serializers.ModelSerializer):
    category1_id = serializers.IntegerField(required=True, label='一级分类id')
    category2_id = serializers.IntegerField(required=True, label='二级分类id')
    category3_id = serializers.IntegerField(required=True, label='三级分类id')
    # category1 = serializers.StringRelatedField(read_only=True, label='一级分类')
    # category2 = serializers.StringRelatedField(read_only=True, label='二级分类')
    # category3 = serializers.StringRelatedField(read_only=True, label='三级分类')

    brand = serializers.StringRelatedField(label='品牌')
    brand_id = serializers.IntegerField(label='品牌ID')

    class Meta:
        model = SPU
        exclude = ['create_time', 'update_time', 'category1', 'category2', 'category3']


class SKUImageSerializer(serializers.ModelSerializer):
    """SKU图片表序列化器"""
    class Meta:
        model = SKUImage
        fields = ['id', 'image', 'sku']
        # read_only_fields = ['sku']

    def create(self, validated_data):
        image: InMemoryUploadedFile = validated_data.get('image')
        from fdfs_client.client import Fdfs_client
        client = Fdfs_client(settings.FDFS_CONF)
        upload_ret = client.upload_by_buffer(image.read())
        if upload_ret['Status'] != 'Upload successed.':
            # 上传失败
            return Response(status=403)
        print(upload_ret['Remote file_id'])
        validated_data['image'] = upload_ret['Remote file_id']
        instance = SKUImage.objects.create(**validated_data)

        # 判断default_image是否为空
        sku = validated_data['sku']
        if not sku.default_image:
            sku.default_image = upload_ret['Remote file_id']
            sku.save()
        # 生成静态详情页
        gen_detail_html.delay(sku.id)
        return instance


class SimpleSKUSerializer(serializers.ModelSerializer):
    """SKU简版序列化器"""
    class Meta:
        model = SKU
        fields = ['id', 'name']
        read_only_fields = ['id', 'name']


class SKUSpecificationSerializer(serializers.ModelSerializer):
    spec_id = serializers.IntegerField(label='规格ID')
    option_id = serializers.IntegerField(label='型号ID')

    class Meta:
        model = SKUSpecification
        fields = ['spec_id', 'option_id']


class SKUSerializer(serializers.ModelSerializer):
    category = serializers.StringRelatedField(label='三级分类名称', read_only=True)
    category_id = serializers.IntegerField(label='三级分类ID')
    spu = serializers.StringRelatedField(label='SPU名称', read_only=True)
    spu_id = serializers.IntegerField()
    specs = SKUSpecificationSerializer(many=True)

    class Meta:
        model = SKU
        fields = ['id', 'name', 'spu', 'spu_id', 'caption', 'category_id', 'category', 'price', 'cost_price', 'market_price', 'stock', 'sales', 'is_launched', 'specs']


class SpecificationOptionSerializer(serializers.ModelSerializer):
    """规格选项表序列化器"""
    spec = serializers.StringRelatedField(read_only=True)
    spec_id = serializers.IntegerField(required=True)

    class Meta:
        model = SpecificationOption
        fields = ['id', 'value', 'spec_id', 'spec']


class GoodsCategorySerializer(serializers.ModelSerializer):
    """商品分类表"""
    parent = serializers.StringRelatedField(required=False, read_only=True)

    class Meta:
        model = GoodsCategory
        exclude = ['create_time', 'update_time']
